new Vue({
  el: "#epaper",
  data: {
    paper: [],
    activeIndex: 0,
    swiperGroupLength: 5,
    period: [],
    mySwiper: null,
    autoStep: 0,
    bookSwiper: null,
    currentActiveBox: null, // 活跃的拖拽容器
    currentActiveImage: null, // 获取的拖拽电子书
    x: undefined, // 鼠标按下时图片相对浏览器的位置
    y: undefined, // 鼠标按下时图片相对浏览器的位置
    DELTA: 1.0, // 每次放大/缩小的倍数
    showScalelog: "100%",
    activeDate: new Date(),
    calendarGrid: 42, // 7 * 6宫格;
    date: new Date(),
    hasDateList: [],
  },
  created() {
    this.$nextTick(() => {
      if (this.bookSwiper) {
        this.bookSwiper.init(); // 使用init方法重新初始化
      } else
        this.bookSwiper = new Swiper(".epaper_book_content", {
          paginationClickable: true,
          simulateTouch: false,
          spaceBetween: 30,
        });
    });
  },
  mounted() {
    const url = new URL(window.location.href);
    const queryParams = new URLSearchParams(url.search);
    const histroyDate = queryParams.get("date");
    if (histroyDate) {
      this.date = new Date(histroyDate);
      this.activeDate = new Date(histroyDate);
      this.getDateOfReport(true, false);
    } else {
      this.getDateOfReport(true, true);
    }
    this.getReportHistory();
  },
  computed: {
    swiperDataLength: function () {
      return this.swiperData.length;
    },
    swiperStep() {
      return this.period.length - this.swiperGroupLength;
    },
  },
  methods: {
    getDateOfReport(flag = false, defaultDate = true) {
      let year = this.date.getFullYear(),
        month = this.date.getMonth() + 1;
      let params;
      if (flag && defaultDate) {
        params = { year };
      } else {
        params = { year, month };
      }
      post("/Index/reportDay", params)
        .then((response) => {
          this.hasDateList = response.data.day.map((i) => i.day_time_text);
          if (this.hasDateList.length && defaultDate) {
            this.date = new Date(this.hasDateList[0]);
            this.activeDate = new Date(this.hasDateList[0]);
          }
          this.getReportInfo(this.date, flag);
          this.renderCalendar(this.date, flag);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getReportInfo(date, create = false) {
      let dateFormat = `${date.getFullYear()}-${
        date.getMonth() + 1
      }-${date.getDate()}`;
      //return get()... 就能then-then
      post("/Index/reportInfo", { date: dateFormat })
        .then((response) => {
          if (!response.data.paper) return;
          this.paper = response.data.paper;
          if (!create) {
            this.resizeBookImg(this.activeIndex);
          }
          this.activeIndex = 0;
          this.$nextTick(() => {
            if (this.bookSwiper) {
              this.bookSwiper.init(); // 使用init方法重新初始化
            } else
              this.bookSwiper = new Swiper(".epaper_book_content", {
                paginationClickable: true,
                simulateTouch: false,
                spaceBetween: 30,
              });
          });
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getReportHistory() {
      post("/Index/reportHistory")
        .then((response) => {
          this.period = response.data.history;
          this.$nextTick(() => {
            if (this.mySwiper) {
              this.mySwiper.init(); // 使用init方法重新初始化
            } else
              this.mySwiper = new Swiper(".e_swi_content", {
                slidesPerView: this.swiperGroupLength,
                paginationClickable: true,
                spaceBetween: 10,
                simulateTouch: false,
              });
          });
        })
        .catch((err) => {
          console.log(err);
        });
    },
    changeMonth(type) {
      let month = 0;
      let year = 1970;
      if (type === "prev") {
        month = this.date.getMonth() === 0 ? 11 : this.date.getMonth() - 1;
        year =
          month === 11 ? this.date.getFullYear() - 1 : this.date.getFullYear();
      } else {
        month = this.date.getMonth() === 11 ? 0 : this.date.getMonth() + 1;
        year =
          month === 0 ? this.date.getFullYear() + 1 : this.date.getFullYear();
      }
      this.date.setDate(1);
      this.date.setMonth(month);
      this.date.setFullYear(year);
      this.getDateOfReport();
    },
    handlePerioditem(item, index) {
      this.resizeBookImg(this.activeIndex);
      this.activeIndex = 0;
      window.open(
        `${window.location.origin}${window.location.pathname}?date=${item.day_time_text}`,
        "_blank"
      );
    },
    handlerPre() {
      this.autoStep--;
      this.mySwiper.slidePrev();
    },
    handlerNext() {
      this.autoStep++;
      this.mySwiper.slideNext();
    },
    // 电子书上一页
    handleBookPre() {
      this.bookSwiper.slidePrev();
      if (this.activeIndex > 0) {
        this.resizeBookImg(this.activeIndex); // 重置上一个
        this.activeIndex--;
      }
    },
    // 电子书下一页
    handleBookNext() {
      this.bookSwiper.slideNext();
      if (this.paper.img_path.length - 1 > this.activeIndex) {
        this.resizeBookImg(this.activeIndex); // 重置上一个
        this.activeIndex++;
      }
    },
    handlePageNav(index) {
      this.bookSwiper.slideTo(index);
      this.resizeBookImg(this.activeIndex);
      this.activeIndex = index;
    },
    handleEBtnControlLeft() {
      if (Math.round(this.DELTA * 100) >= 400) {
        return;
      }
      let { id: activeId } = this.paper.img_path[this.bookSwiper.activeIndex];
      this.currentActiveBox = this.$refs[`bookPageC${this.activeIndex}`][0]; // 容器
      this.currentActiveImage = this.$refs[`bookPageI${this.activeIndex}`][0]; // 图片
      let transf = this.getTransform(this.currentActiveImage);
      this.DELTA += 0.2;
      let newTransf = this.limitBorder(
        this.currentActiveImage,
        this.currentActiveBox,
        transf.transX,
        transf.transY,
        this.DELTA
      );
      this.currentActiveImage.style.transform = `matrix(${this.DELTA}, 0, 0, ${this.DELTA}, ${newTransf.transX}, ${newTransf.transY})`;
      this.showScalelog = `${Math.round(this.DELTA * 100)}%`;
    },
    // 缩小
    handleEBtnControlRight() {
      if (Math.round(this.DELTA * 100) <= 80) return;
      let { id: activeId } = this.paper.img_path[this.bookSwiper.activeIndex];
      this.currentActiveBox = this.$refs[`bookPageC${this.activeIndex}`][0]; // 容器
      this.currentActiveImage = this.$refs[`bookPageI${this.activeIndex}`][0]; // 图片
      let transf = this.getTransform(this.currentActiveImage);
      this.DELTA -= 0.2;
      let newTransf = this.limitBorder(
        this.currentActiveImage,
        this.currentActiveBox,
        transf.transX,
        transf.transY,
        this.DELTA
      );
      this.currentActiveImage.style.transform = `matrix(${this.DELTA}, 0, 0, ${this.DELTA}, ${newTransf.transX}, ${newTransf.transY})`;
      this.showScalelog = `${Math.round(this.DELTA * 100)}%`;
    },
    // 重置
    resizeBookImg(activeIndex) {
      this.currentActiveImage = this.$refs[`bookPageI${activeIndex}`][0]; // 图片
      this.currentActiveImage.style.transform = `matrix(1, 0, 0,1, 0, 0)`;
      this.DELTA = 1.0;
      this.showScalelog = `${Math.round(this.DELTA * 100)}%`;
    },
    // 鼠标按下
    mouseDown(e, activeId) {
      this.currentActiveBox = this.$refs[`bookPageC${activeId}`][0]; // 容器
      this.currentActiveImage = this.$refs[`bookPageI${activeId}`][0]; // 图片
      let transf = this.getTransform(this.currentActiveImage);
      this.x = e.clientX - transf.transX; // 图片初始位置
      this.y = e.clientY - transf.transY; // 图片初始位置
      this.currentActiveBox.addEventListener("mousemove", this.mouseMove);
      this.currentActiveBox.addEventListener("mouseup", this.mouseUp);
    },
    mouseMove(e) {
      let multiple = this.getTransform(this.currentActiveImage).multiple;
      let moveX = e.clientX - this.x; // x向移动距离
      let moveY = e.clientY - this.y; // y向移动距离
      let newTransf = this.limitBorder(
        this.currentActiveImage,
        this.currentActiveBox,
        moveX,
        moveY,
        multiple
      );
      this.currentActiveImage.style.transform = `matrix(${multiple}, 0, 0, ${multiple}, ${newTransf.transX}, ${newTransf.transY})`;
    },
    // 鼠标抬起 移除监听器
    mouseUp() {
      this.currentActiveBox?.removeEventListener("mousemove", this.mouseMove);
      this.currentActiveBox?.removeEventListener("mouseup", this.mouseUp);
      this.currentActiveImage = null;
      this.currentActiveBox = null;
    },
    // 鼠标滚轮缩放 更新transform
    zoom(e, activeId) {
      e.preventDefault();
      if (e.deltaY < 0) {
        if (Math.round(this.DELTA * 100) >= 400) return;
        this.DELTA += 0.2;
      } else {
        if (Math.round(this.DELTA * 100) <= 80) return;
        this.DELTA -= 0.2;
      }
      this.currentActiveBox = this.$refs[`bookPageC${activeId}`][0]; // 容器
      this.currentActiveImage = this.$refs[`bookPageI${activeId}`][0]; // 图片
      let transf = this.getTransform(this.currentActiveImage);
      let newTransf = this.limitBorder(
        this.currentActiveImage,
        this.currentActiveBox,
        transf.transX,
        transf.transY,
        this.DELTA
      );
      this.currentActiveImage.style.transform = `matrix(${this.DELTA}, 0, 0, ${this.DELTA}, ${newTransf.transX}, ${newTransf.transY})`;
      this.showScalelog = `${Math.round(this.DELTA * 100)}%`;
    },
    getTransform(DOM) {
      let arr = getComputedStyle(DOM).transform.split(",");
      return {
        transX: isNaN(+arr[arr.length - 2]) ? 0 : +arr[arr.length - 2], // 获取translateX
        transY: isNaN(+arr[arr.length - 1].split(")")[0])
          ? 0
          : +arr[arr.length - 1].split(")")[0], // 获取translateX
        multiple: +arr[3], // 获取图片缩放比例
      };
    },
    limitBorder(innerDOM, outerDOM, moveX, moveY, multiple) {
      let {
        clientWidth: innerWidth,
        clientHeight: innerHeight,
        offsetLeft: innerLeft,
        offsetTop: innerTop,
      } = innerDOM;
      let { clientWidth: outerWidth, clientHeight: outerHeight } = outerDOM;
      let transX;
      let transY;
      // 放大的图片超出box时 图片最多拖动到与边框对齐
      if (
        innerWidth * multiple > outerWidth ||
        innerHeight * multiple > outerHeight
      ) {
        if (
          innerWidth * multiple > outerWidth &&
          innerHeight * multiple > outerHeight
        ) {
          transX = Math.min(
            Math.max(
              moveX,
              outerWidth - (innerWidth * (multiple + 1)) / 2 - innerLeft
            ),
            -innerLeft + (innerWidth * (multiple - 1)) / 2
          );
          transY = Math.min(
            Math.max(
              moveY,
              outerHeight - (innerHeight * (multiple + 1)) / 2 - innerTop
            ),
            -innerTop + (innerHeight * (multiple - 1)) / 2
          );
        } else if (
          innerWidth * multiple > outerWidth &&
          !(innerHeight * multiple > outerHeight)
        ) {
          transX = Math.min(
            Math.max(
              moveX,
              outerWidth - (innerWidth * (multiple + 1)) / 2 - innerLeft
            ),
            -innerLeft + (innerWidth * (multiple - 1)) / 2
          );
          transY = Math.max(
            Math.min(
              moveY,
              outerHeight - (innerHeight * (multiple + 1)) / 2 - innerTop
            ),
            -innerTop + (innerHeight * (multiple - 1)) / 2
          );
        } else if (
          !(innerWidth * multiple > outerWidth) &&
          innerHeight * multiple > outerHeight
        ) {
          transX = Math.max(
            Math.min(
              moveX,
              outerWidth - (innerWidth * (multiple + 1)) / 2 - innerLeft
            ),
            -innerLeft + (innerWidth * (multiple - 1)) / 2
          );
          transY = Math.min(
            Math.max(
              moveY,
              outerHeight - (innerHeight * (multiple + 1)) / 2 - innerTop
            ),
            -innerTop + (innerHeight * (multiple - 1)) / 2
          );
        }
      }
      // 图片小于box大小时 图片不能拖出边框
      else {
        transX = Math.max(
          Math.min(
            moveX,
            outerWidth - (innerWidth * (multiple + 1)) / 2 - innerLeft
          ),
          -innerLeft + (innerWidth * (multiple - 1)) / 2
        );
        transY = Math.max(
          Math.min(
            moveY,
            outerHeight - (innerHeight * (multiple + 1)) / 2 - innerTop
          ),
          -innerTop + (innerHeight * (multiple - 1)) / 2
        );
      }
      return { transX, transY };
    },
    handleDateChange(e) {
      let date = e.target.dataset?.date;
      if (date) {
        const today = new Date();
        const content = document.getElementById("e_calendar_content");
        // 判断是否小于当前日期
        if (
          date <=
          `${today.getFullYear()}${
            today.getMonth() + 1 >= 10
              ? today.getMonth() + 1
              : "0" + (today.getMonth() + 1)
          }${today.getDate() >= 10 ? today.getDate() : "0" + today.getDate()}`
        ) {
          this.activeDate = new Date(
            `${date.slice(0, 4)}/${date.slice(4, 6)}/${date.slice(6, 8)}`
          );
          // 清空其他
          const children = Array.from(content.children).slice(1);
          children.map((item) => {
            if (date == item.dataset.date) {
              this.addClassNames(item, "active");
            } else {
              this.removeClassNames(item, "active");
            }
          });
          this.getReportInfo(this.activeDate);
        }
      }
    },

    // 是否为闰年
    isLeap(year) {
      return (year % 4 === 0 && year % 100 !== 0) || year % 100 === 0;
    },

    // 获取[month]月有几天
    getDays(year, month) {
      const feb = this.isLeap(year) ? 29 : 28;
      const daysPerMonth = [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      return daysPerMonth[month];
    },

    // 获取下个月/上个月有多少天
    getNextOrLastMonthDays(date, type) {
      const month = date.getMonth();
      const year = date.getFullYear();
      if (type === "last") {
        // 如果当前月份为一月(month = 0), 则上个月为前一年的12月(month = 11)
        const lastMonth = month === 0 ? 11 : month - 1;
        const lastYear = lastMonth === 11 ? year - 1 : year;
        return {
          year: lastYear,
          month: lastMonth,
          days: this.getDays(lastYear, lastMonth),
        };
      }
      // 如果当前月份为12月(month = 11), 则上个月为下一年的1月(month = 0)
      const nextMonth = month === 11 ? 0 : month + 1;
      const nextYear = nextMonth === 0 ? year + 1 : year;
      return {
        year: nextYear,
        month: nextMonth,
        days: this.getDays(nextYear, nextMonth),
      };
    },
    // 生成日历数据
    generateCalendar(date) {
      const currentYear = date.getFullYear();
      const currentMonth = date.getMonth();
      // 当月天数
      const days = this.getDays(currentYear, currentMonth);
      // 获取上月末尾天数和下月开头的天数，用于填补当月日历空白
      const {
        days: lastMonthDays,
        year: lastMonthYear,
        month: lastMonth,
      } = this.getNextOrLastMonthDays(date, "last");
      const { year: nextMonthYear, month: nextMonth } =
        this.getNextOrLastMonthDays(date, "next");
      // 1号是星期几
      const weekIndex = new Date(
        `${currentYear}/${currentMonth + 1}/1`
      ).getDay();
      // 显示在当月末尾的下月天数
      const trailDays = this.calendarGrid - weekIndex - days;
      let trailVal = 0;
      const calendarTable = [];
      for (let i = 0; i < this.calendarGrid; i++) {
        // 补充上月天数
        if (i < weekIndex) {
          calendarTable[i] = {
            year: lastMonthYear,
            month: lastMonth,
            day: lastMonthDays - weekIndex + i + 1,
            isCurrentMonth: false,
          };
          // 补充下月天数
        } else if (i >= days + weekIndex) {
          if (trailVal < trailDays) {
            trailVal += 1;
          }
          calendarTable[i] = {
            year: nextMonthYear,
            month: nextMonth,
            day: trailVal,
            isCurrentMonth: false,
          };
        }
      }
      // 填充当月日期
      for (let d = 1; d <= days; d++) {
        calendarTable[weekIndex + d - 1] = {
          year: currentYear,
          month: currentMonth,
          day: d,
          isCurrentMonth: true,
        };
      }

      return calendarTable;
    },

    // 几个工具函数
    addClassNames(docNode, classNames) {
      classNames.split(" ").forEach((c) => {
        c && docNode.classList.add(c);
      });
    },

    removeClassNames(docNode, classNames) {
      classNames.split(" ").forEach((c) => {
        c && docNode.classList.remove(c);
      });
    },

    // 渲染日历
    renderCalendar(date = new Date(), create = false) {
      const calendarData = this.generateCalendar(date);
      const today = new Date();
      this.setDateInfo();
      const content = document.getElementById("e_calendar_content");
      // 动态创建标签，初始化时调用
      if (create) {
        const fragment = document.createDocumentFragment();
        calendarData.forEach((item) => {
          const li = document.createElement("li");
          const div = document.createElement("div");
          const isActive = [
            item.day === this.activeDate.getDate(),
            item.month === this.activeDate.getMonth(),
            item.year === this.activeDate.getFullYear(),
            item.isCurrentMonth,
          ].every(Boolean);
          const isToday = [
            item.day === today.getDate(),
            item.month === today.getMonth(),
            item.year === today.getFullYear(),
            item.isCurrentMonth,
          ].every(Boolean);
          let currentDate = this.timeFormat(item.year, item.month, item.day);
          const isCliclk = this.hasDateList.includes(currentDate);
          const liClass = `date flex justify-center align-center ${
            isToday ? "activetoday" : ""
          } ${isActive ? "active" : ""} ${item.isCurrentMonth ? "" : "light"} ${
            isCliclk ? "click" : ""
          }`;
          if (isCliclk) {
            li.dataset.date = this.timeFormat(
              item.year,
              item.month,
              item.day,
              ""
            );
            div.dataset.date = this.timeFormat(
              item.year,
              item.month,
              item.day,
              ""
            );
          }
          this.addClassNames(div, "date-num flex justify-center align-center");
          this.addClassNames(li, liClass);
          div.innerText = item.day;
          li.appendChild(div);
          li.addEventListener("click", this.handleDateChange, false);
          fragment.appendChild(li);
        });

        content.append(fragment);
      } else {
        const children = Array.from(content.children).slice(1);
        calendarData.forEach((item, index) => {
          const isActive = [
            item.day === this.activeDate.getDate(),
            item.month === this.activeDate.getMonth(),
            item.year === this.activeDate.getFullYear(),
            item.isCurrentMonth,
          ].every(Boolean);
          const isToday = [
            item.day === today.getDate(),
            item.month === today.getMonth(),
            item.year === today.getFullYear(),
            item.isCurrentMonth,
          ].every(Boolean);
          let currentDate = this.timeFormat(item.year, item.month, item.day);
          const isCliclk = this.hasDateList.includes(currentDate);
          isCliclk
            ? this.addClassNames(children[index], "click")
            : this.removeClassNames(children[index], "click");

          children[index].childNodes[0].innerText = item.day;
          if (isCliclk) {
            // 修改dataSet
            children[index].dataset.date = this.timeFormat(
              item.year,
              item.month,
              item.day,
              ""
            );
            children[index].childNodes[0].dataset.date = this.timeFormat(
              item.year,
              item.month,
              item.day,
              ""
            );
          } else {
            children[index].dataset.date = "";
            children[index].childNodes[0].dataset.date = "";
          }
          isActive
            ? this.addClassNames(children[index], "active")
            : this.removeClassNames(children[index], "active");
          isToday
            ? this.addClassNames(children[index], "activetoday")
            : this.removeClassNames(children[index], "activetoday");

          item.isCurrentMonth
            ? this.removeClassNames(children[index], "light")
            : this.addClassNames(children[index], "light");
        });
      }
    },
    setDateInfo() {
      const year = this.date.getFullYear();
      const month = this.date.getMonth() + 1;
      document.querySelector(
        ".e_content_top .e_content_top_right .e_calendar .calendar_title"
      ).innerText = `${year}年${month < 10 ? "0" + month : month}月`;
      document.getElementById("e_calendar_bg").innerText = month;
    },

    changeToToday() {
      this.date = new Date();
      this.renderCalendar(date);
    },
    handlePrev() {
      this.changeMonth("prev");
    },
    handleNext() {
      this.changeMonth("next");
    },
    timeFormat(year, month = null, day = null, str = "-") {
      if (year && month != null && day != null) {
        return `${year}${str}${
          month + 1 < 10 ? "0" + (month + 1) : month + 1
        }${str}${day < 10 ? "0" + day : day}`;
      } else if (year && month != null) {
        return `${year}${str}${month + 1 < 10 ? "0" + (month + 1) : month + 1}`;
      } else if (year) {
        return `${year}`;
      }
      return "";
    },
  },
});
